"""
事件系统 - 实现松耦合的模块间通信
支持：
1. 发布-订阅模式
2. 异步事件处理
3. 事件中间件
4. 事件持久化
"""

import asyncio
from typing import Dict, List, Callable, Any, Optional, Union
from dataclasses import dataclass, field
from datetime import datetime
import json
import weakref
from enum import Enum
import traceback
from .interfaces import EventInterface


class EventPriority(Enum):
    """事件优先级"""
    LOW = 1
    NORMAL = 2
    HIGH = 3
    CRITICAL = 4


@dataclass
class Event:
    """事件模型"""
    type: str
    data: Dict[str, Any]
    source: str = ""
    timestamp: datetime = field(default_factory=datetime.now)
    priority: EventPriority = EventPriority.NORMAL
    correlation_id: Optional[str] = None
    metadata: Dict[str, Any] = field(default_factory=dict)
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            "type": self.type,
            "data": self.data,
            "source": self.source,
            "timestamp": self.timestamp.isoformat(),
            "priority": self.priority.value,
            "correlation_id": self.correlation_id,
            "metadata": self.metadata
        }
    
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> 'Event':
        """从字典创建事件"""
        return cls(
            type=data["type"],
            data=data["data"],
            source=data.get("source", ""),
            timestamp=datetime.fromisoformat(data["timestamp"]),
            priority=EventPriority(data.get("priority", EventPriority.NORMAL.value)),
            correlation_id=data.get("correlation_id"),
            metadata=data.get("metadata", {})
        )


class EventHandler:
    """事件处理器包装"""
    
    def __init__(self, handler: Callable, priority: int = 0, filter_func: Optional[Callable] = None):
        self.handler = handler
        self.priority = priority
        self.filter_func = filter_func
        
    async def can_handle(self, event: Event) -> bool:
        """检查是否能处理该事件"""
        if self.filter_func:
            if asyncio.iscoroutinefunction(self.filter_func):
                return await self.filter_func(event)
            else:
                return self.filter_func(event)
        return True
        
    async def handle(self, event: Event):
        """处理事件"""
        if asyncio.iscoroutinefunction(self.handler):
            await self.handler(event)
        else:
            self.handler(event)


class EventBus(EventInterface):
    """
    事件总线 - 实现发布-订阅模式
    支持事件路由、中间件、持久化等功能
    """
    
    def __init__(self):
        self._subscribers: Dict[str, List[EventHandler]] = {}
        self._middlewares: List[Callable] = []
        self._event_queue: asyncio.Queue = asyncio.Queue()
        self._running = False
        self._worker_task: Optional[asyncio.Task] = None
        self._event_history: List[Event] = []
        self._max_history = 1000
        
    async def start(self):
        """启动事件处理器"""
        if not self._running:
            self._running = True
            self._worker_task = asyncio.create_task(self._process_events())
            
    async def stop(self):
        """停止事件处理器"""
        self._running = False
        if self._worker_task:
            self._worker_task.cancel()
            try:
                await self._worker_task
            except asyncio.CancelledError:
                pass
                
    async def publish(self, event_type: str, data: Dict[str, Any], **kwargs):
        """
        发布事件
        
        Args:
            event_type: 事件类型
            data: 事件数据
            **kwargs: 其他事件属性
        """
        event = Event(type=event_type, data=data, **kwargs)
        
        # 应用中间件
        for middleware in self._middlewares:
            try:
                if asyncio.iscoroutinefunction(middleware):
                    event = await middleware(event)
                else:
                    event = middleware(event)
                    
                if event is None:
                    return  # 中间件拦截了事件
            except Exception as e:
                print(f"Middleware error: {e}")
                
        # 加入队列
        await self._event_queue.put(event)
        
    async def subscribe(
        self, 
        event_type: str, 
        handler: Callable,
        priority: int = 0,
        filter_func: Optional[Callable] = None
    ):
        """
        订阅事件
        
        Args:
            event_type: 事件类型 (支持通配符 *)
            handler: 处理函数
            priority: 优先级 (数字越大优先级越高)
            filter_func: 过滤函数
        """
        if event_type not in self._subscribers:
            self._subscribers[event_type] = []
            
        event_handler = EventHandler(handler, priority, filter_func)
        self._subscribers[event_type].append(event_handler)
        
        # 按优先级排序
        self._subscribers[event_type].sort(key=lambda x: x.priority, reverse=True)
        
    def unsubscribe(self, event_type: str, handler: Callable):
        """取消订阅"""
        if event_type in self._subscribers:
            self._subscribers[event_type] = [
                h for h in self._subscribers[event_type] 
                if h.handler != handler
            ]
            
    def add_middleware(self, middleware: Callable):
        """添加中间件"""
        self._middlewares.append(middleware)
        
    async def _process_events(self):
        """处理事件队列"""
        while self._running:
            try:
                # 等待事件
                event = await asyncio.wait_for(self._event_queue.get(), timeout=1.0)
                
                # 记录事件历史
                self._add_to_history(event)
                
                # 查找匹配的订阅者
                handlers = self._find_handlers(event.type)
                
                # 并发处理事件
                tasks = []
                for handler in handlers:
                    if await handler.can_handle(event):
                        task = asyncio.create_task(self._safe_handle_event(handler, event))
                        tasks.append(task)
                        
                if tasks:
                    await asyncio.gather(*tasks, return_exceptions=True)
                    
            except asyncio.TimeoutError:
                continue
            except Exception as e:
                print(f"Event processing error: {e}")
                
    def _find_handlers(self, event_type: str) -> List[EventHandler]:
        """查找事件处理器"""
        handlers = []
        
        # 精确匹配
        if event_type in self._subscribers:
            handlers.extend(self._subscribers[event_type])
            
        # 通配符匹配
        for pattern, pattern_handlers in self._subscribers.items():
            if '*' in pattern:
                if self._match_pattern(pattern, event_type):
                    handlers.extend(pattern_handlers)
                    
        return handlers
        
    def _match_pattern(self, pattern: str, event_type: str) -> bool:
        """模式匹配"""
        if pattern == '*':
            return True
            
        # 简单的通配符匹配实现
        pattern_parts = pattern.split('*')
        if len(pattern_parts) == 2:
            prefix, suffix = pattern_parts
            return event_type.startswith(prefix) and event_type.endswith(suffix)
            
        return False
        
    async def _safe_handle_event(self, handler: EventHandler, event: Event):
        """安全地处理事件"""
        try:
            await handler.handle(event)
        except Exception as e:
            error_event = Event(
                type="system.error",
                data={
                    "original_event": event.to_dict(),
                    "error": str(e),
                    "traceback": traceback.format_exc()
                },
                source="event_bus"
            )
            # 发布错误事件（但不要造成无限循环）
            if event.type != "system.error":
                await self._event_queue.put(error_event)
                
    def _add_to_history(self, event: Event):
        """添加到事件历史"""
        self._event_history.append(event)
        if len(self._event_history) > self._max_history:
            self._event_history.pop(0)
            
    def get_event_history(self, event_type: Optional[str] = None, limit: int = 100) -> List[Event]:
        """获取事件历史"""
        history = self._event_history
        if event_type:
            history = [e for e in history if e.type == event_type]
        return history[-limit:]


# 全局事件总线实例
event_bus = EventBus()


def event_handler(event_type: str, priority: int = 0, filter_func: Optional[Callable] = None):
    """
    事件处理器装饰器
    
    Usage:
        @event_handler("user.registered")
        async def handle_user_registered(event: Event):
            print(f"New user: {event.data['username']}")
    """
    def decorator(func):
        asyncio.create_task(event_bus.subscribe(event_type, func, priority, filter_func))
        return func
    return decorator


class EventEmitter:
    """
    事件发射器 Mixin
    为类添加事件发布能力
    """
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._event_source = self.__class__.__name__
        
    async def emit(self, event_type: str, data: Dict[str, Any], **kwargs):
        """发射事件"""
        kwargs.setdefault('source', self._event_source)
        await event_bus.publish(event_type, data, **kwargs)
        
    async def emit_success(self, operation: str, data: Dict[str, Any] = None):
        """发射成功事件"""
        await self.emit(f"{operation}.success", data or {})
        
    async def emit_error(self, operation: str, error: Exception):
        """发射错误事件"""
        await self.emit(f"{operation}.error", {
            "error": str(error),
            "error_type": type(error).__name__
        })


# 预定义的系统事件类型
class SystemEvents:
    """系统事件类型常量"""
    
    # 数据层事件
    DOCUMENT_INDEXED = "data.document.indexed"
    DOCUMENT_UPDATED = "data.document.updated"
    DOCUMENT_DELETED = "data.document.deleted"
    
    # 检索事件
    SEARCH_PERFORMED = "retrieval.search.performed"
    SEARCH_RESULTS_RERANKED = "retrieval.results.reranked"
    
    # 智能体事件
    TASK_RECEIVED = "agent.task.received"
    TASK_STARTED = "agent.task.started"
    TASK_COMPLETED = "agent.task.completed"
    TASK_FAILED = "agent.task.failed"
    
    # 系统事件
    SYSTEM_STARTED = "system.started"
    SYSTEM_STOPPED = "system.stopped"
    ERROR_OCCURRED = "system.error"
    
    # 工作流事件
    WORKFLOW_STARTED = "workflow.started"
    WORKFLOW_COMPLETED = "workflow.completed"
    WORKFLOW_FAILED = "workflow.failed"